﻿using System;
using System.Text;
using System.Web;
using FBGraph.Web.Configuration;

namespace FBGraph.Web.Security
{
    /// <summary>Contains helper methods used for authorization in web applications.</summary>
    public static class FBGraphAuthorizationHelper
    {
        /// <summary>Determines whether the current user meets the authorization requirements for the current request.</summary>
        /// <param name="handler">The <see cref="IFBGraphAuthorizationHandler" /> handling the request.</param>
        /// <param name="httpContext">The current <see cref="HttpContextBase" /> for the request.</param>
        /// <param name="scope">A value representing the mapping of <see cref="ExtendedPermission" /> values required for the request.</param>
        /// <returns><c>true</c> if the user is authorized; otherwise, <c>false</c>.</returns>
        public static Boolean Authorize(this IFBGraphAuthorizationHandler handler, HttpContextBase httpContext, ExtendedPermission scope)
        {
            var context = FBGraphHttpContext.Current(httpContext);

            if (context.IsAuthorized)
            {
                // if the user has already granted all the requested permissions, nothing left to do here
                if ((context.ExtendedPermissions & scope) == scope) return true;
            }

            return false;
        }

        /// <summary>Redirects the user to authorize the application and/or authorize extended permissions after failing authorization.</summary>
        /// <param name="handler">The <see cref="IFBGraphAuthorizationHandler" /> handling the request.</param>
        /// <param name="httpContext">The current <see cref="HttpContextBase" /> for the request.</param>
        /// <param name="scope">A value representing the mapping of <see cref="ExtendedPermission" /> values required for the request.</param>
        /// <remarks>
        /// If the request has been made by an Ajax client, the redirect url is inserted into the <see cref="HttpContextBase.Items" /> dictionary to be used later
        /// to return the url to the client.
        /// </remarks>
        public static void ExecuteAuthorizationRedirect(this IFBGraphAuthorizationResultHandler handler, HttpContextBase httpContext, ExtendedPermission scope)
        {
            var context = FBGraphHttpContext.Current(httpContext);

            var uri = httpContext.Request.Url;
            var baseUri = new UriBuilder(uri);
            baseUri.Path = String.Empty;

            var redirect = new UriBuilder(new Uri(baseUri.Uri, VirtualPathUtility.MakeRelative(String.Empty, context.Config.GetAuthUrl())));
            if (!redirect.Path.EndsWith("/")) redirect.Path += "/";
            redirect.Path += "authorize";

            var queryBuilder = new StringBuilder(redirect.Query);
            if (queryBuilder.Length > 0 && !queryBuilder.ToString().EndsWith("&")) queryBuilder.Append("&");
            queryBuilder.Append("scope=");
            queryBuilder.Append(scope);
            queryBuilder.Append("&returnUrl=");
            queryBuilder.Append(HttpUtility.UrlEncode((httpContext.Request.IsAjaxRequest() ? httpContext.Request.UrlReferrer : httpContext.Request.Url).ToString()));
            redirect.Query = queryBuilder.ToString();

            if (httpContext.Request.IsAjaxRequest())
            {
                httpContext.Items["FBGraphAuthorizeAttribute_Redirect"] = redirect.ToString();
            }
            else httpContext.Response.Redirect(redirect.ToString());
        }
    }
}